# ------------------------------------------------------------------------------
# Autor:             terrasky
# Date:              2024-03-27 ~ 2024-09-20
# Ver:               v1.0 
# ------------------------------------------------------------------------------
# _*_ coding:UTF-8 _*_

# :env:       Python 3.8.7
## FileStruct ################################################################
# 1     CheckTool.py                    主程序
# 2     cad.py                          cad相关模块
# 3     config.py                       程序配置模块
# 4     gtypes.py                       与cad通信需要的数据结构转换模块
# 5     logger.py                       处理日志模块
# 6     CheckToolUI.py                  处理程序界面模块
# 7     addDataDialog.py                添加菜单界面模块
# 8     QEnterPlainTextEdit.py          自定义特殊组件
# ------------------------------------------------------------------------------

import sys,re,os,csv
from datetime import datetime
import math

from CheckToolUI import Ui_Form
from addDataDialog import Ui_Dialog
from config import appModel,appData
from cad import CAD
from gtypes import GPoint,GRect,vtint,vtvariant,vt2dpnt
from logger import LOG
# from PyQt5.Qt import QWidget,QDialog,QApplication,Qt
from PyQt5.Qt import *
# from PyQt5.Qt import QWidget,
from openpyxl import load_workbook  # 调用本地库
import pymysql  # 调用网络库

from docx import Document
from docx.shared import Inches
from docx.enum import text

class MainWindow(QWidget, Ui_Form):
    def __init__(self):
        super().__init__()
        # 调用父类setupUi函数
        self.setupUi(self)
        self.setWindowFlags(Qt.WindowStaysOnTopHint) # 设置窗口最前端显示

        # private object
        self.initData()

        # 调用private function
        self.updata_treeWidget()   # 更新treeWidget显示
        self.getResiveData_and_updataTWinput()

        # 链接信号-槽
        self.treeWidget.clicked.connect(self.updata_tableWidget)
        self.fiterlineEdit.textChanged.connect(self.fiterlineEdit_Changed)
        self.plainTextEdit.returnPressed.connect(self.plainTextEdit_Enter)
        self.tableWidget.cellDoubleClicked.connect(self.tableWidget_doubleClicked)
        self.tableWidget_input.clicked.connect(self.tableWidget_input_Clicked)
        self.tableWidget_input.mouseRightBtnClicked.connect(self.tableWidget_input_mouseRightBtnClicked)
        self.tableWidget_input.mouseMidBtnClicked.connect(self.tableWidget_input_mouseMidBtnClicked)
        self.commentButton.clicked.connect(self.commentButton_Clicked)
        self.showButton.clicked.connect(self.showButton_Clicked)
        self.pb_sys.clicked.connect(self.pb_sys_Clicked)
        # self.pb_sys_2.clicked.connect(self.test)
        self.pb_sys_2.clicked.connect(self.pb_about_Clicked)
        self.wordButton.clicked.connect(self.wordButtonClicked)

        self.tableWidget.customContextMenuRequested.connect(self.tableMenuAdd)  # 响应右键菜单


    def initData(self):
        # private object
        appData.load()
        self.type_modle = appData.type_model

        # 读取数据库
        if self.type_modle == appModel.NET:    # 优先检查为网络版
            self.mysqlData =  self.readMysqlData()   # 启用网络或本地数据库
            if not self.mysqlData :
                self.type_modle = appModel.FILE
            self.setWindowTitle('图纸校审工具CheckTool 【网络校审版】')
        if self.type_modle == appModel.FILE:
            self.mysqlData =  self.readDataFile()    # 启用本地或网络数据库
            if not self.mysqlData :
                self.type_modle = appModel.READ
            self.setWindowTitle('图纸校审工具CheckTool 【本地校审版】')
        if self.type_modle == appModel.READ:
            self.mysqlData = None
            self.setWindowTitle('图纸校审工具CheckTool 【查看版】')

        # 初始化私有数据及对象
        self.treeModelData = self.getTreeModelData()    # 读取tree 树模型数据 json list
        self.tableModelData = []  # 读取table 树模型数据 json list,仅仅在点击tree后更新
        self.readlyToDataBase = []  # 待入库数据
        self.resive_datas = []            # : List(Dict{}) 保存tableWidget_input订正框信息
        self.last_select_item = None    # 用于记录上次选择的框注rect对象，
        self.cad = self.initCad()
        self.lineEdit.setText( appData._Config['AUTOR'] )
        
        # 创建【校审】图层
        if self.cad:
            lay = self.cad.doc.Layers.Add(appData.default_lay)
            lay.color = 6
            lay.Lineweight = 50

    # ====================== updata =============================
    def update_tableWidget_input(self):     # 根据self.resive_datas更新 tableWidget_input
        self.tableWidget_input.clear()
        self.tableWidget_input.setRowCount(len(self.resive_datas))
        self.tableWidget_input.setColumnCount(1)
        self.tableWidget_input.horizontalHeader().setStretchLastSection(True)
        self.tableWidget_input.verticalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)

        for row_index,item in enumerate(self.resive_datas):
            rect_item = item.get('context')
            # 显示表内容
            if rect_item == None:
                tableItem = QTableWidgetItem('...')
                tableItem.setBackground(QColor(255,0,0,100))
            else:
                tableItem = QTableWidgetItem(str(rect_item))
            self.tableWidget_input.setItem(row_index,0,tableItem)
        self.tableWidget_input.resizeRowsToContents()


    def updata_treeWidget(self):        # 根据self.treeModelData更新 treeWidget
        """更新树型列表"""
        self.treeWidget.clear()

        # 若根目录无数据，则不显示知识库
        if not self.treeModelData:
            self.treeWidget.setVisible(False)
            self.widget_2.setVisible(False)
            self.wordButton.setVisible(False)
            self.plainTextEdit.setVisible(False)
            self.widget_10.setVisible(False)
            return

        # 增加系统标签
        for key,value in self.treeModelData.items():
            tree_top_item = QTreeWidgetItem(self.treeWidget)
            tree_top_item.setText(0,key)
            self.treeWidget.addTopLevelItem(tree_top_item)
            self.treeWidget.expandItem(tree_top_item)
            for col_key in value:
                tree_sec_item = QTreeWidgetItem(tree_top_item)
                tree_sec_item.setText(0,col_key)


    def updata_tableWidget(self):       # 根据self.mysqlData更新显示 tableWidget
        """点击treeWidget后并更新tableWidget列表数据"""

        # 更新TableModelData数据
        self.tableModelData = self.getTableModelData()
        self.tableModelData.extend(self.readlyToDataBase)
        fiter_data = self.tableModelData

        # 更新界面
        self.tableWidget.clear()
        self.tableWidget.setRowCount(len(fiter_data))
        self.tableWidget.setColumnCount(len(appData.seqs))

        # 设置表头
        for index,item in enumerate(appData.seqs):
            item = QTableWidgetItem(str(item))
            self.tableWidget.setHorizontalHeaderItem(index,item)

        # 显示表内容 根据self.tableModelData
        for row_index,db in enumerate(fiter_data):
            for col_index,key in enumerate(appData.seqs_id):
                showtext = db[key]
                if not showtext:
                    showtext = ''
                it = QTableWidgetItem(str(showtext))

                # 若是待入库数据，则填入背景色
                if db[appData.key_names[0]] == -1:
                    it.setBackground(QColor(44, 111, 111))
                    it.setForeground(QColor(255,255,255))
                    
                self.tableWidget.setItem(row_index,col_index,it)
        self.resize_tableWidget()

        
    # ====================== connect =============================
    def tableWidget_doubleClicked( self, row: int, column: int):
        """双击知识库后 给输入框插入内容"""

        # 获取数据
        context = self.tableModelData[row]['context']
        context1 = self.tableModelData[row]['gui']
        context2 = self.tableModelData[row]['guiCont']

        # 输入框插入内容
        self.plainTextEdit.insertPlainText(context)
        if context1:
            self.plainTextEdit.insertPlainText("不满足"+context1)
            if context2:
                self.plainTextEdit.insertPlainText("中"+context2+"的要求。")
            else:
                self.plainTextEdit.insertPlainText("。")

        # hothit 加一
        if self.type_modle == appModel.FILE:
            pass
        elif self.type_modle == appModel.NET:
            def addhothit():
                try:
                    db = pymysql.connect(
                        host="mysql.sqlpub.com", 
                        port=3306,user="terrasky",
                        password="RhFiMuNSoyiuGsgp", 
                        db="terrasky", 
                        charset='utf8mb4')
                except Exception as e:
                    LOG.logger.debug(f'hothit服务器请求失败:{e}')
                    return False 
                if not db : 
                    LOG.logger.debug(f'数据库不存在')
                    return False

                cursor = db.cursor()
                data = (context,context1,context2)
                sql = f"update guifan set hothit=hothit+1 where context=(%s) and gui=(%s) and guiCont=(%s)"

                try:
                    cursor.execute(sql, data)
                    db.commit()
                except pymysql.Error as e:
                    db.rollback()
                    LOG.logger.debug(f'入库MySql失败:{e}')
                    db.close()
                    return False
                db.close()
                return True

            if addhothit():
                LOG.logger.info(f'hothit已加一')
            else:
                LOG.logger.info('hothit加一错误')


    def tableWidget_input_Clicked(self):
        # 显示所选定的校审框对象
        if self.last_select_item:
            try:
                self.last_select_item.Highlight(False)
            except Exception as e:
                LOG.logger.debug(f'对象Highlight设定False错误')
        index_row = self.tableWidget_input.currentRow()
        
        try:
            obj = self.resive_datas[index_row]['rect_item']
            pts = obj.GetBoundingBox()
        except Exception as e:
            LOG.logger.debug(f'list index out of range')
            return

        # 移动视图焦点
        pt1 = GPoint(pts[0])
        pt2 = GPoint(pts[1])
        w = abs(pt2.x - pt1.x)
        h = abs(pt2.y - pt1.y)
        pt1 = pt1 + GPoint(-w*1.1, -h*1.1) 
        pt2 = pt2 + GPoint(w*1.1, h*1.1)
        self.cad.ZoomWindow(pt1,pt2)

        # 高亮显示对象
        try:
            obj.Highlight(True)
        except Exception as e:
            LOG.logger.debug(f'对象Highlight设定True错误')
        self.last_select_item = obj


    def tableWidget_input_mouseRightBtnClicked(self):
        """将校审框对象文字复制到所选定的tableWidget""" 
        if self.type_modle == appModel.READ:    # 只读模式下不予响应
            return 
        self.plainTextEdit_Enter()  # 等价于按了回车


    def tableWidget_input_mouseMidBtnClicked(self):
        """ 复制内容文字到审框内 """
        if self.type_modle == appModel.READ:    # 只读模式下不予响应
            return 
        index_row = self.tableWidget_input.currentRow()
        text = self.resive_datas[index_row].get('context')
        self.plainTextEdit.insertPlainText(text)


    def plainTextEdit_Enter(self):
        # 赋值给对应打印框
        context = self.plainTextEdit.toPlainText()
        row = self.tableWidget_input.currentRow()

        if row != -1:   # 选择了tableWidget_input对象
            # 更新输入框的内容
            self.resive_datas[row]['context'] = context
            self.resive_datas[row]['autor'] = self.lineEdit.text()
            self.resive_datas[row]['time'] = datetime.now().strftime("%Y-%m-%d")
            obj = self.resive_datas[row]['rect_item']
            self.plainTextEdit.clear()
            self.update_tableWidget_input()

            # 写入cad对象属性
            self.writeCadObjectData(obj,context)


    def responseMenu(self,action):
        # 相应菜单
        if action.text() == "添加行":
            def addLine():
                index = self.treeWidget.selectedIndexes()[0]
                sec_text = self.treeWidget.itemFromIndex(index).text(0)
                top_text = self.treeWidget.itemFromIndex(index.parent()).text(0)

                # 生成临时字典记录 待入库数据
                temp = {}
                temp['id'] = -1 # -1 ID 用于记录是待入库数据
                temp['file'] = top_text
                temp['type'] = sec_text
                temp['context'] = dialog.contextEdit.toPlainText()
                temp['gui'] = dialog.guiEdit.text()
                temp['guiCont'] = dialog.guiContEdit.text()
                temp['tagname'] = dialog.tagnameEdit.text()
                temp['hothit'] = 0
                temp['userName'] = self.lineEdit.text()
                self.readlyToDataBase.append(temp)
                self.updata_tableWidget()

            dialog = addDataDialog()
            dialog.setWindowFlags(Qt.WindowStaysOnTopHint) # 设置窗口最前端显示
            dialog.contextEdit.setPlainText(self.plainTextEdit.toPlainText())
            if dialog.exec_():
                addLine()
                

        elif action.text() == '删除行':
            # 删除行必须是待入库对象
            def deleteRow():
                current = self.tableWidget.currentRow()
                tableRow = len(self.tableModelData)
                readlyRow = len(self.readlyToDataBase)
                i = current - (tableRow - readlyRow)
                if i >= 0:
                    del self.readlyToDataBase[i]
                    self.updata_tableWidget()
            deleteRow()

        elif action.text() == '入库':
            if self.saveToFileOrSql():
                LOG.logger.info(f'入库成功')
                self.lb_msg.setText(f"入库成功")
            else:
                LOG.logger.info(f'入库失败')

 
    def saveToFileOrSql(self):  # ->Bool 入库成功返回True
        # 入库
        if not self.readlyToDataBase:
            return False
        
        def toFile():
            # 入库到本地文件   
            try:
                wb = load_workbook(appData.excel_file_name)
            except:
                LOG.logger.debug(f'打开{appData.excel_file_name}文件失败')
                self.lb_msg.setText(f"打开本地文件失败，检查文件【{appData.excel_file_name}】是否存在")
                return False
            ws = wb.active
            max_row = ws.max_row
            for i,item in enumerate(self.readlyToDataBase):
                item[appData.key_names[0]] = max_row + i 
                # 将字典的值入库
                ws.append([item.get(index) for index in appData.key_names])
                
            # 保存本地文件
            try:
                wb.save(appData.excel_file_name)
            except:
                LOG.logger.debug(f'保存{appData.excel_file_name}文件失败')
                self.lb_msg.setText(f"保存文件失败，检查文件【{appData.excel_file_name}】是否关闭")
                return False
            return True

        def toSql():
            # 入库到网络库
            try:
                db = pymysql.connect(
                    host="mysql.sqlpub.com", 
                    port=3306,user="terrasky",
                     password="RhFiMuNSoyiuGsgp", 
                     db="terrasky", 
                     charset='utf8mb4')
            except Exception as e:
                LOG.logger.debug(f'入库服务器请求失败:{e}')
                self.lb_msg.setText(f"入库服务器请求失败....")
                return False 
            if not db : 
                LOG.logger.debug(f'数据库不存在')
                return False

            cursor = db.cursor()
            data = list([tuple(dic[key] for key in appData.key_names[1:]) for dic in self.readlyToDataBase])
            sql = f"insert into guifan ({','.join(appData.key_names[1:])}) values (%s,%s,%s,%s,%s,%s,%s,%s)"

            try:
                cursor.executemany(sql, data)
                db.commit()
            except pymysql.Error as e:
                db.rollback()
                LOG.logger.debug(f'入库MySql失败:{e}')
                db.close()
                return False
            db.close()
            return True

        # 数据入库
        if self.type_modle == appModel.FILE:
            isSuccee = toFile()
        elif self.type_modle == appModel.NET:
            isSuccee = toSql()

        # 如果入库成功，改变待入库数据状态和样式
        if isSuccee:
            self.mysqlData.extend(self.readlyToDataBase)
            self.readlyToDataBase = []
            self.updata_tableWidget()

        return isSuccee


    def tableMenuAdd(self,pos):     # table右键菜单显示
        selectedIndexes = self.treeWidget.selectedIndexes()
        # 若没有选中主标签，则不相应
        if not selectedIndexes:
            return
        
        # 若选中一级标题，则不相应
        if selectedIndexes[0].parent().row() == -1:    # 选中的根目录
            return

        # 生成菜单
        menu = QMenu(self)
 
        # 添加一些菜单项
        menu.addAction("添加行")
        menu.addAction("删除行")
        menu.addAction("入库")
 
        # 设置菜单触发信号与槽函数的连接
        menu.triggered.connect(self.responseMenu)
 
        # 在鼠标点击的位置显示菜单
        menu.exec_(self.tableWidget.viewport().mapToGlobal(pos))


    def commentButton_Clicked(self):
        self.getResiveData_and_updataTWinput()


    def getResiveData_and_updataTWinput(self):
        # 通过全局获取批注框，将数据写人 self.resive_datas，并更新tableWidget_input
        if not self.cad:
            return
        
        #自动获取批注框
        self.resive_datas = [] # : List(Dict{})
        filterType=vtint([-4,0,8,-4] )  # 0 图元类型；8 图层名称
        filterData=vtvariant( ['<AND','LWPolyline',appData.default_lay,'AND>'] )
        try:
            item_list = [item for item in self.cad.get_selection_by_all(filterType=filterType,filterData=filterData) ]   
        except Exception as e:
            LOG.logger.error(f"自动获取打印框错误：{e}")
            return

        # 通过获取的批准框，将数据写人 self.resive_datas
        for item in item_list:
            print_dic = {}
            print_dic['rect_item'] = item

            # 获取对象批准内容
            if item.GetXData('autor')[0]:
                print_dic['autor'] = item.GetXData('autor')[1][1]
            if item.GetXData('context')[0]:    
                print_dic['context'] = item.GetXData('context')[1][1]
            if item.GetXData('time')[0]:
                print_dic['time'] = item.GetXData('time')[1][1]

            self.resive_datas.append(print_dic)

        # 更新tableWidget_input
        self.update_tableWidget_input()


    def showButton_Clicked(self):
        # 删除所有校审内容（Mtext）
        if not self.clearReviseMText():
            return

        # 在方框右侧写入校审内容
        for item in self.resive_datas:
            obj = item['rect_item']
            context =  '审批：' + item.get('autor','') + '\\P'
            context += '时间：' + item.get('time','') + '\\P'
            context += '意见：' + item.get('context','')

            pts = obj.GetBoundingBox()

            # 移动视图焦点
            pt1 = GPoint(pts[0])
            pt2 = GPoint(pts[1])

            # 依据图框确定文字高度
            w = abs(pt2.x - pt1.x)
            h = abs(pt2.y - pt1.y)
            rate = 1 if math.log10(w*h) <4 else 1000   # 文字大小倍率
            height = 0.35 * rate    # 文字大小

            # cad中写入文字
            mtextobj = self.cad.ms.AddMText(pt2,height,context)
            mtextobj.Height = height
            mtextobj.Layer = appData.default_lay
            mtextobj.Width = rate * 50


    def pb_sys_Clicked(self):
        # 重新初始化数据
        appData._Config['AUTOR'] = self.lineEdit.text()
        appData.save()
        self.initData()
        self.updata_treeWidget()
        self.getResiveData_and_updataTWinput()


    def pb_about_Clicked(self):
        # 版权消息对话框
        about = "{0:^80} \n{1:^80}\n{2:^80}".format(
            appData.app_name, appData.app_ver,appData.copyright)
        a = QMessageBox.about(self,'版权声明',about)


    def wordButtonClicked(self):
        # 创建一个新的文档对象
        if self.cad: 
            doc = Document()
            basename = os.path.basename(self.cad.doc.name)
            fileName = os.path.join(self.cad.filepath,f'【意见】{basename}.docx')
        else:
            self.lb_msg.setText(f"保存失败")
            return

        # 添加一个段落
        paragraph = doc.add_paragraph(f"{basename}校审意见")
        paragraph.style = 'Title'

        # dirname, filename = os.path.split(os.path.abspath(sys.argv[0]))
        dirname=os.path.dirname(os.path.abspath(sys.argv[0]))
        jpgfilename = os.path.join(dirname, 'temp.jpg')
        for index,item in enumerate(self.resive_datas):
            # 获取属性
            context = item.get('context')
            autor = item.get('autor')
            time = item.get('time')
            obj = item.get('rect_item')
            pt1,pt2 = obj.GetBoundingBox()
            pt1 = GPoint(pt1)
            pt2 = GPoint(pt2)

            #调节视口范围
            tw = abs(pt2.x - pt1.x)
            th = abs(pt2.y - pt1.y)

            h = 0.8 * tw if 0.8*tw>th else th
            w = 1.25 * th if 1.25*th>tw else tw 

            print(f'{pt1=},{pt2=}')
            pt1 = pt1 + GPoint(-w*1.0, -h*1.0) 
            pt2 = pt2 + GPoint(w*1.0, h*1.0)
            print(f'{pt1=},{pt2=}')
            # 写入文字段落
            # doc.add_paragraph(f"{index+1}、【{autor}】{time}")
            doc.add_paragraph(f"{index+1}、【{autor}】{time}")
            doc.add_paragraph(f"{context}")

            # 写入图片
            if self.cad.printJPG(pt1, pt2, jpgfilename):
                # 写入图片
                jpg = doc.add_picture(jpgfilename, height=Inches(2.5))

                # 图片居中
                last_paragraph = doc.paragraphs[-1]
                last_paragraph.alignment = text.WD_ALIGN_PARAGRAPH.CENTER

        # 保存文档
        try:
            doc.save(fileName)
            self.lb_msg.setText(f"保存成功: {fileName}")
        except:
            self.lb_msg.setText(f"保存失败")


# ====================== private function =============================
    def initCad(self):      # ->cad object
        cad = CAD()
        if cad.isCadConnect:
            self.lb_msg.setText(f"成功链接: {cad.doc.name}")
            return cad
        else:
            self.lb_msg.setText("未链接成功。。")
            return None


    def resizeEvent(self,event):    # overload resizeEvent
        self.resize_tableWidget()
        super().resizeEvent(event)


    def fiterlineEdit_Changed(self,text):
        self.updata_tableWidget()


    # def readMysqlData(self) ->list[dict[str,str]] | None:    # 读取网络知识库
    def readMysqlData(self) :    # 读取网络知识库
        """
        读取网络知识库
        """
        try:
            db = pymysql.connect(
                host="mysql.sqlpub.com", 
                port=3306,user="terrasky",
                 password="RhFiMuNSoyiuGsgp", 
                 db="terrasky", 
                 charset='utf8mb4')
        except Exception as e:
            LOG.logger.debug(f'服务器请求失败:{e}')
            return None 
        if not db : 
            return None

        cursor = db.cursor()
        cursor.execute("select * from guifan order by hothit desc")
        results = cursor.fetchall()
        db.close()

        dbList = [dict(zip(appData.key_names,item)) for item in results]
        LOG.logger.info(f'读取MySql成功')
        return dbList


    def getTreeModelData(self) : # 构建tree模型数据 
        """
        根据数据库数据 更新tree模型数据:data=
        {
            treeTop:[treeSec],
        }
        """
        
        treeModelData = {}
        if not self.mysqlData:
            return None
        for db in self.mysqlData:
            treeTop = db.get('file')
            if treeTop in treeModelData.keys():
                treeSec = db.get('type')
                if treeSec not in treeModelData[treeTop]:
                    treeModelData[treeTop].append(treeSec)
            else:
                treeModelData[treeTop] = []

        return treeModelData


    def getTableModelData(self):
        # 获取treeWidget 选择的相关参数
        index = self.treeWidget.selectedIndexes()[0]
        parent_row = index.parent().row()   
        row = index.row()

        if parent_row == -1:    # 选中的根目录
            isexpanded = self.treeWidget.isExpanded(index)
            self.treeWidget.setExpanded(index,not isexpanded)
            return self.mysqlData
        else:   # 选中的系统标签
            sec_text = self.treeWidget.itemFromIndex(index).text(0)
            top_text = self.treeWidget.itemFromIndex(index.parent()).text(0)
            
            # 过滤出一二级标题相同的db
            fiter_data = list(filter(lambda x : x.get('file')==top_text and x.get('type')==sec_text,
                self.mysqlData))

            # 过滤出用户输入的context匹配的db
            fiter = self.fiterlineEdit.text()
            if fiter:
                fiter_data = list(filter(lambda x : fiter in x['context'],fiter_data))
        return fiter_data


    # def readDataFile(self) ->list[dict[str,str]] | None:    # 读取知识库 （从文件）
    def readDataFile(self) :    # 读取知识库 （从文件）
        """
        return ->data = [Dict()]

        """

        # 仅支持单文件作为本地数据库
        try:
            wb = load_workbook(appData.excel_file_name)
        except:
            LOG.logger.debug(f'打开{appData.excel_file_name}文件失败')
            return None

        # 读取数据  
        dbList = []
        worksheets = wb.worksheets
        for ws in worksheets:
            newdata = [dict(zip(appData.key_names,item)) for item in ws.values]
            newdata.pop(0)  # 删除表头部分
            dbList.extend(newdata)
        LOG.logger.info(f'读取本地File成功')
        return dbList
   

    def resize_tableWidget(self) ->None:
        # 拉伸表格
        width = self.tableWidget.horizontalHeader().width()
        self.tableWidget.setColumnWidth(0,int(width*0.60))
        self.tableWidget.setColumnWidth(1,int(width*0.20))
        self.tableWidget.setColumnWidth(2,int(width*0.1))
        self.tableWidget.setColumnWidth(3,int(width*0.1))
        self.tableWidget.horizontalHeader().setStretchLastSection(True)
        self.tableWidget.verticalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)


    def test(self):
        print(f'{self.cad.doc.ModelSpace.Units=}')
        print('in test')


    def setXData(self,obj,key :str,value :str):
        # 设置对象属性
        filterType=vtint( [1001, 1000] )  # 1001 应用程序名；1000保存数据
        filterData=vtvariant([key, value])
        obj.SetXData(filterType,filterData)
        # if self.last_select_item:
        #     self.last_select_item.SetXData(filterType,filterData)
 
    def writeCadObjectData(self,obj,context):
        self.setXData(obj,'autor', self.lineEdit.text())
        self.setXData(obj,'context', context)
        self.setXData(obj,'time', datetime.now().strftime("%Y-%m-%d"))


    def clearReviseMText(self):
        filterType=vtint([-4,0,8,-4] )  # 0 图元类型；8 图层名称
        filterData=vtvariant( ['<AND','MText',appData.default_lay,'AND>'] )
        try:#.GetBoundingBox()
            for mtext in self.cad.get_selection_by_all(filterType=filterType,filterData=filterData):
                mtext.Delete()
        except Exception as e:
            LOG.logger.error(f"删除mtext错误：{e}")
            return False
        return True

class addDataDialog(QDialog,Ui_Dialog):
    def __init__(self):
        super().__init__()
        self.setupUi(self)



if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    
    window.show()
    sys.exit(app.exec_())
    
    